data Tree a = Node a [Tree a]| Leaf a | Nil

nivel:: Tree a -> Int -> [a]
nivel Nil _ = []
nivel (Leaf x) 0 = [x]
nivel (Leaf x) (n+1) = []
nivel (Node r _) 0 = [r]
nivel (Node r xs) (n+1) = tratar xs n

tratar:: [Tree a] -> Int -> [a]
tratar [Nil] _ = [] 
tratar [] _ = []
tratar (x:xs) n = nivel x n ++ tratar xs n

--f :: Tree a -> Int -> [a]
--f Nil _ = []
--f (Leaf x) 0 = [x]
--f (Leaf x) (n+1) = []
--f (Node r xs) n 
	--	| n == 0 = [r]	  
	--	| n > 0  = tratar xs (n-1)

-- depth first search
dfs :: Tree a -> [a]
dfs Nil = []
dfs (Leaf x) = [x]
dfs (Node r xs) = [r] ++ dfsList xs

dfsList :: [Tree a] -> [a]
dfsList [] = []
dfsList [Nil] = []
dfsList [Leaf x] = [x]
dfsList (x:xs) = dfs x ++ dfsList xs  	

-- breadth first search

bfs :: Tree a -> [a]
bfs Nil = []
bfs (Leaf x) = [x]
bfs (Node r []) = [r]
bfs (Node r (x:xs)) = [r] ++ bfsList(x:xs) []	

bfsList :: [Tree a] -> [Tree a] -> [a]
bfsList [] [] = []
bfsList [] xs = bfsList xs []
bfsList [Nil] xs = bfsList xs []
bfsList [Leaf x] xs = [x] ++ bfsList xs []
bfsList ((Node r xs):ys) zs = [r] ++ bfsList ys (zs++xs)
bfsList (Nil:xs) zs = bfsList xs zs
